<template>
  <div :ref="yearPicker" class="yearPicker">
    <div class="_inner" :style="{ width: props.labelWidth + 'px' }">{{ props.labelText }}</div>
    <px-icon @click.stop="onFocus"><Calendar /></px-icon>
    <input
      :ref="inputLeft"
      v-model="data.startShowYear"
      class="_inner"
      type="text"
      name="yearInput"
      placeholder="开始年份"
      @focus="onFocus"
      @click="clickInput"
      @input="checkStartInput()"
    />
    <span>{{ props.sp }}</span>
    <input
      :ref="inputRight"
      v-model="data.endShowYear"
      class="_inner"
      type="text"
      name="yearInput"
      placeholder="结束年份"
      @focus="onFocus"
      @click="clickInput"
      @input="checkEndInput()"
    />
    <px-icon v-if="clearable" class="clearIcon" @click="clearInput"><CircleClose /></px-icon>
    <div v-if="data.showPanel" class="_inner floatPanel">
      <div class="_inner leftPanel">
        <div class="_inner panelHead"><i class="_inner" @click="onClickLeft">&lt;&lt;</i> {{ leftYearList[0] + "-" + leftYearList[9] }}</div>

        <div class="_inner panelContent">
          <div
            v-for="item in leftYearList"
            :key="item"
            :class="{
              disabled: checkValidYear(item),
              oneSelected: item === data.startYear && oneSelected,
              startSelected: item === data.startYear,
              endSelected: item === data.endYear,
              _inner: true,
              betweenSelected: item > data.startYear && item < data.endYear
            }"
          >
            <a
              :class="{
                cell: true,
                _inner: true,
                selected: item === data.startYear || item === data.endYear
              }"
              @click="onClickItem(item)"
              @mouseover="onHoverItem(item)"
            >
              {{ item }}
            </a>
          </div>
        </div>
      </div>

      <div class="_inner rightPanel">
        <div class="_inner panelHead">
          <i class="_inner" @click="onClickRight">&gt;&gt;</i>
          {{ rightYearList[0] + "-" + rightYearList[9] }}
        </div>

        <div class="_inner panelContent">
          <div
            v-for="item in rightYearList"
            :key="item"
            :class="{
              disabled: checkValidYear(item),
              startSelected: item === data.startYear,
              endSelected: item === data.endYear,
              betweenSelected: item > data.startYear && item < data.endYear
            }"
          >
            <a
              :class="{
                cell: true,
                _inner: true,
                selected: item === data.endYear || item === data.startYear
              }"
              @click="onClickItem(item)"
              @mouseover="onHoverItem(item)"
            >
              {{ item }}
            </a>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { VNodeRef, computed, nextTick, onBeforeMount, onBeforeUnmount, onMounted, reactive, ref } from "vue";
interface Emits {
  (e: "updateTimeRange", startYear: number, endYear: number): void;
}
interface Props {
  labelWidth: number;
  labelText: string;
  sp?: string;
  initYear?: { startYear: number; endYear: number };
  clearable?: boolean;
}
const SELECT_STATE = {
  unselect: 0,
  selecting: 1,
  selected: 2
};

let yearS = new Date().getFullYear();
let yearE = new Date().getFullYear();
const props = withDefaults(defineProps<Props>(), {
  labelWidth: 80,
  labelText: "时间标签",
  sp: "-",
  clearable: true // 是否可清空，默认是
});
const data = reactive<any>({
  itemBg: {},
  startShowYear: props.initYear.startYear,
  endShowYear: yearE,
  yearList: [],
  showPanel: false,
  startYear: null,
  endYear: null,
  curYear: 0,
  curSelectedYear: 0,
  curState: SELECT_STATE.unselect
});
const yearPicker = ref<VNodeRef>();
const inputLeft = ref<VNodeRef>();
const inputRight = ref<VNodeRef>();
const oneSelected = computed(() => {
  return data.curState === SELECT_STATE.selecting && (data.startYear === data.endYear || data.endYear == null);
});
const leftYearList = computed(() => {
  return data.yearList.slice(0, 10);
});
const rightYearList = computed(() => {
  return data.yearList.slice(10, 20);
});
const clearInput = () => {
  data.startShowYear = null;
  data.endShowYear = null;
  data.startYear = null;
  data.endYear = null;
};
const emits = defineEmits<Emits>();

const clickInput = (e: any) => {
  e.stopPropagation();
  return false;
};
const checkValidYear = (iYear: number) => {
  // if (props.initYear) {
  //   if (iYear > props.initYear.endYear) {
  //     return 1;
  //   } else if (iYear < props.initYear.startYear) {
  //     return -1;
  //   }
  // }
  return 0;
};
const checkStartInput = () => {
  if (isNaN(data.startShowYear)) {
    data.startShowYear = data.startYear;
  } else {
    data.startYear = data.startShowYear * 1;
  }
};
const checkEndInput = () => {
  if (isNaN(data.endShowYear)) {
    data.endShowYear = data.endYear;
  } else {
    data.endYear = data.endShowYear * 1;
  }
};
const changeYear = () => {
  if (data.startYear > data.endYear) {
    let tmp = data.endYear;
    data.endYear = data.startYear;
    data.startYear = tmp;
  }
  if (props.initYear) {
    data.startYear = Math.max(data.startYear, props.initYear.startYear);
    data.endYear = Math.min(data.endYear, props.initYear.endYear);
  }
  data.startShowYear = data.startYear;
  data.endShowYear = data.endYear;
  if (data.startYear && data.endYear) {
    emits("updateTimeRange", data.startYear, data.endYear);
  } else {
    data.startShowYear = data.startShowYear ? data.startShowYear : new Date().getFullYear();
    data.endShowYear = data.endShowYear ? data.endShowYear : new Date().getFullYear();
    emits("updateTimeRange", data.startShowYear, data.endShowYear);
    // console.warn("WARN:年份不合法", data.startYear, data.endYear);
  }
};
const onHoverItem = (iYear: number) => {
  if (checkValidYear(iYear) != 0) {
    return;
  }
  if (data.curState === SELECT_STATE.selecting) {
    let tmpStart = data.curSelectedYear;
    data.endYear = Math.max(tmpStart, iYear);
    data.startYear = Math.min(tmpStart, iYear);
  }
};
const onClickItem = (iYear: number) => {
  if (checkValidYear(iYear) != 0) {
    return;
  }
  if (data.curState === SELECT_STATE.unselect || data.curState === SELECT_STATE.selected) {
    data.startYear = iYear;
    data.curSelectedYear = iYear;
    data.endYear = null;
    data.curState = SELECT_STATE.selecting;
  } else if (data.curState === SELECT_STATE.selecting) {
    // 处理双击年份，导致结束日志bug
    if (!data.endYear && data.startYear == iYear) {
      data.endYear = iYear;
    }
    data.endShowYear = data.endYear;
    data.startShowYear = data.startYear;
    data.curState = SELECT_STATE.selected;
    emits("updateTimeRange", data.startYear, data.endYear);
    setTimeout(() => {
      //为动画留的时间，可优化
      data.showPanel = false;
    }, 300);
  }
};
const onFocus = () => {
  nextTick(() => {
    data.showPanel = true;
  });
};
const updateYearList = () => {
  let iStart = Math.floor(data.curYear / 10) * 10 - 10;
  iStart = iStart < 0 ? 0 : iStart;
  data.yearList = [];
  for (let index = 0; index < 20; index++) {
    data.yearList.push(iStart + index);
  }
};
const closePanel = (e: any) => {
  if (!data.showPanel) {
    return;
  }
  if (typeof e.target.className !== "string" || e.target.className === "") {
    nextTick(() => {
      changeYear();
      data.showPanel = false;
    });
    return;
  }
  if (
    e.target.className.indexOf("_inner") === -1 ||
    (e.target.name === "yearInput" && e.target !== inputLeft.value && e.target !== inputRight.value)
  ) {
    nextTick(() => {
      changeYear();
      data.showPanel = false;
    });
  }
  e.stopPropagation();
  return false;
};
const onClickLeft = () => {
  data.curYear = data.curYear * 1 - 10;
  updateYearList();
};
const onClickRight = () => {
  data.curYear = data.curYear * 1 + 10;
  updateYearList();
};
onBeforeMount(() => {
  data.curYear = new Date().getFullYear();
  updateYearList();
});
onBeforeUnmount(() => {
  document.removeEventListener("click", closePanel.bind(data));
});
onMounted(() => {
  document.addEventListener("click", closePanel.bind(data));
});
</script>
<style lang="scss" scoped>
.yearPicker {
  position: relative;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;

  // border: 1px solid #eff1f3;
  height: 32px;
  padding: 0 8px;
  font-size: 14px;
  line-height: 32px;
  background-color: #fff;
  border-radius: 4px;
  transition: all 0.3s;

  .clearIcon {
    opacity: 0;
  }

  input:first-child {
    text-align: right;
  }

  span {
    height: 32px;
    padding: 0 8px;
    line-height: 32px;
  }

  .floatPanel {
    position: absolute;
    top: 40px;
    left: -158px;
    z-index: 2000;
    display: flex;
    width: 650px;
    height: 180px;
    padding: 0 16px;
    background-color: #fff;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);

    > div {
      width: 50%;
    }

    .panelContent {
      display: flex;
      flex-wrap: wrap;
      width: 100%;
      height: calc(100% - 70px);

      .disabled {
        color: #ccc;
      }

      .oneSelected {
        border-top-right-radius: 24px;
        border-bottom-right-radius: 24px;
      }

      .startSelected {
        background-color: #f6f6f7;
        border-top-left-radius: 24px;
        border-bottom-left-radius: 24px;
      }

      .endSelected {
        background-color: #f6f6f7;
        border-top-right-radius: 24px;
        border-bottom-right-radius: 24px;
      }

      .betweenSelected {
        background-color: #f6f6f7;
      }

      > div {
        width: 75px;
        height: 36px;
        margin: 3px 0;
        line-height: 36px;
        // border-radius: 24px;
        text-align: center;

        a {
          display: inline-block;
          width: 60px;
          height: 32px;
          line-height: 32px;
          cursor: pointer;
          border-radius: 18px;
        }

        .selected {
          color: #fff;
          background-color: #3e77fc;
        }
      }
    }

    .panelHead {
      position: relative;
      height: 36px;
      line-height: 36px;
      text-align: center;

      i {
        position: absolute;
        cursor: pointer;

        &:hover {
          color: #3e77fc;
        }
      }
    }

    .rightPanel {
      padding-left: 8px;
    }

    .leftPanel .panelHead i {
      left: 20px;
    }

    .rightPanel .panelHead i {
      right: 20px;
    }
  }

  .floatPanel::before {
    position: absolute;
    left: 50%;
    width: 1px;
    height: 100%;
    content: "";
    border-left: 1px solid #e4e4e4;
  }
}

.px-icon {
  color: var(--px-text-color-placeholder);
}

input {
  box-sizing: border-box;
  width: 39%;
  height: 32px;
  line-height: 32px;
  text-align: center;
  background-color: transparent;
  border: none;
}

input:focus {
  background-color: transparent;
  outline: none;
}

input::placeholder {
  color: var(--px-text-color-placeholder);
}

.yearPicker:hover .clearIcon {
  // border-color: #3e77fc;
  opacity: 1;
}

.dateIcon {
  position: absolute;
  top: 9px;
  right: 16px;
  color: #adb2bc;
}
</style>
